package org.itzixi.controller;


import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.itzixi.RedisKeyConstant;
import org.itzixi.RequestConstant;
import org.itzixi.enums.PlatformEnum;
import org.itzixi.enums.RedisKeyEnum;
import org.itzixi.excptions.GraceException;
import org.itzixi.grace.result.GraceJSONResult;
import org.itzixi.grace.result.ResponseStatusEnum;
import org.itzixi.pojo.Users;
import org.itzixi.pojo.bo.RegistryLoginBO;
import org.itzixi.pojo.vo.UsersVO;
import org.itzixi.service.UsersService;
import org.itzixi.utils.IPUtil;
import org.itzixi.utils.RedisOperator;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/passport")
public class PassportController {

    @Resource
    private RedisOperator redisOperator;

//    @Resource
//    private SMSTask smsTask;
    @Resource
    private UsersService usersService;



    @GetMapping("/getSMSCode")
    public GraceJSONResult smsTask(String mobile, HttpServletRequest request)  {
        if (StringUtils.isBlank(mobile)) return GraceJSONResult.error();

        String userIP = IPUtil.getRequestIp(request);
        String redisUserIPKey = StrUtil.join(":", "mobile", "smscode", userIP);
        redisOperator.setnx60s(redisUserIPKey, mobile);
        String code = (int)((Math.random() * 9 + 1) * 100000) + "";
//        smsTask.sendSMS(mobile, code);

        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        redisOperator.set(redisKey, code, 30 * 60);


        return GraceJSONResult.ok();
    }

    @PostMapping("/registry")
    public GraceJSONResult<UsersVO> registry(@RequestBody @Valid RegistryLoginBO registryLoginBO)  {
        String mobile = registryLoginBO.getMobile();
        String smsCode = registryLoginBO.getSmsCode();
        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        String smsCodeVal = redisOperator.get(redisKey);
        if (StringUtils.isBlank(smsCodeVal) || !smsCodeVal.equalsIgnoreCase(smsCode)){
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        Users users = usersService.queryMobileIfExist(mobile);
        if (users != null) GraceJSONResult.errorCustom(ResponseStatusEnum.USER_ALREADY_EXIST_ERROR);
        users = usersService.createUsers(mobile, registryLoginBO.getNickname());
        redisOperator.del(redisKey);
        // 生成令牌
        UsersVO usersVO = buildUserToken(users);
        return GraceJSONResult.ok(usersVO);
    }

    @PostMapping("/login")
    public GraceJSONResult<UsersVO> login(@RequestBody @Valid RegistryLoginBO registryLoginBO)  {
        String mobile = registryLoginBO.getMobile();
        String smsCode = registryLoginBO.getSmsCode();

        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        String smsCodeVal = redisOperator.get(redisKey);
        if (StringUtils.isBlank(smsCodeVal) || !smsCodeVal.equalsIgnoreCase(smsCode)){
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        Users users = usersService.queryMobileIfExist(mobile);
        if (users == null) return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        redisOperator.del(redisKey);
        // 生成令牌
//        UsersVO usersVO = buildUserToken(users);
        String userAppToken = PlatformEnum.TOKEN_APP_PREFIX.getType() + StrUtil.DOT + UUID.randomUUID().toString();
        redisOperator.set(RedisKeyEnum.REDIS_USER_TOKEN.getKey() + userAppToken, users.getId());
        UsersVO usersVO = new UsersVO();
        usersVO.setUserToken(userAppToken);
        BeanUtils.copyProperties(users, usersVO);
        return GraceJSONResult.ok(usersVO);
    }


    @PostMapping("/logout")
    public GraceJSONResult<Void> logout(HttpServletRequest request)  {
        String userToken = request.getHeader(RequestConstant.HEADER_USER_TOKEN);
        redisOperator.del(RedisKeyEnum.REDIS_USER_TOKEN.getKey()+userToken);
        return GraceJSONResult.ok();
    }


    /**
     * 生成用户令牌
     * @param users
     * @return
     */
    private UsersVO buildUserToken(Users users){
        String userAppToken = PlatformEnum.TOKEN_APP_PREFIX.getType() + StrUtil.DOT + UUID.randomUUID().toString();
        redisOperator.set(RedisKeyEnum.REDIS_USER_TOKEN.getKey() + userAppToken, users.getId());
        UsersVO usersVO = new UsersVO();
        usersVO.setUserToken(userAppToken);
        BeanUtils.copyProperties(users, usersVO);
        return usersVO;
    }
}
